{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import datasets\n",
    "iris=datasets.load_iris()\n",
    "X=iris.data[:,2:]#选取后两个特征\n",
    "y=iris.target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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tGmTioqKTHfLtdavX6+6ujrt3bvXdFc8YcqUKaqpqVFhYaGam5v1/e9/X1dffbUaGho0cOBA091znTfffFOPPvqoKioqdPfdd2vv3r367ne/q/T0dJWVlZnunus9/fTTev/997VgwQJHzk8xgqiUl5eroaGBZ9MRKCwsVH19vVpbW/Wf//mfKisr044dOyhIgmhqatLtt9+uLVu2qH///qa74wkXPmoeM2aMpkyZooKCAv32t7/Vt7/9bYM9cye/369JkybpgQcekCSNHz9eDQ0NWrFiBcVIBH79619rzpw5Gj58uCPn5zENIrZ48WJt3rxZL7/8skaMGGG6O66Xnp6uz372s5o4caKqqqo0duxY/fznPzfdLVfav3+/jh8/rgkTJigtLU1paWnasWOHHn74YaWlpamjo8N0F13vk5/8pC6//HIdPHjQdFdcadiwYb3+IfD5z3+eR1sROHLkiLZu3apbb73VsWvwzQjCCgQCuu2227Rp0yZt376dSV8x8vv9OnfunOluuNKXv/xlvfrqqz22LVy4UFdccYXuvPNOpaamGuqZd5w6dUp/+ctf9M1vftN0V1xp6tSpvZYkeOONN1RQUGCoR96xevVq5eTkaO7cuY5dIymLkVOnTvX418OhQ4dUX1+vwYMH67LLLjPYM3cqLy/XunXr9Mwzz2jgwIFqaWmRJGVnZyszM9Nw79ypsrJSc+bM0WWXXaaTJ09q3bp12r59u1544QXTXXOlgQMH9pqD9IlPfEJDhgxhblII//qv/6obbrhBBQUFevvtt7V06VKlpqbq5ptvNt01V7rjjjtUUlKiBx54QF/72te0Z88erVy5UitXrjTdNVfz+/1avXq1ysrKlJbmYMkQSEIvv/xyQFKvT1lZmemuuVKweyUpsHr1atNdc61vfetbgYKCgkB6enpg6NChgS9/+cuBF1980XS3PGX69OmB22+/3XQ3XKu0tDQwbNiwQHp6euBTn/pUoLS0NHDw4EHT3XK13/3ud4HRo0cHMjIyAldccUVg5cqVprvkei+88EJAUuD111939Dq+QCAQcK7UAQAAsMYEVgAAYBTFCAAAMIpiBAAAGEUxAgAAjKIYAQAARlGMAAAAoyhGAACAURQjAADAKIoRAABgFMUIAAAwimIEAAAYRTECAACM+v9TbeFHwEqE2gAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#可视化\n",
    "plt.scatter(X[y==0,0],X[y==0,1])\n",
    "plt.scatter(X[y==1,0],X[y==1,1])\n",
    "plt.scatter(X[y==2,0],X[y==2,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-2 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: black;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-2 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-2 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-2 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-2 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-2 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 1ex;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-2 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>DecisionTreeClassifier(criterion=&#x27;entropy&#x27;, max_depth=2)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" checked><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;DecisionTreeClassifier<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.tree.DecisionTreeClassifier.html\">?<span>Documentation for DecisionTreeClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>DecisionTreeClassifier(criterion=&#x27;entropy&#x27;, max_depth=2)</pre></div> </div></div></div></div>"
      ],
      "text/plain": [
       "DecisionTreeClassifier(criterion='entropy', max_depth=2)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#使用scikit-learn的决策树\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "dt_clf=DecisionTreeClassifier(max_depth=2,criterion=\"entropy\")\n",
    "dt_clf.fit(X,y)#训练数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"决策边界绘制函数\"\"\"\n",
    "def plot_decision_boundary(model, axis):\n",
    "    x0, x1 = np.meshgrid(\n",
    "        np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1, 1),\n",
    "        np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1, 1)\n",
    "    )\n",
    "    X_new = np.c_[x0.ravel(), x1.ravel()]\n",
    "    y_predict = model.predict(X_new)\n",
    "    zz = y_predict.reshape(x0.shape)\n",
    "\n",
    "    from matplotlib.colors import ListedColormap\n",
    "    custom_cmap = ListedColormap(['#EF9A9A', '#FFF59D', '#90CAF9'])\n",
    "\n",
    "    plt.contourf(x0, x1, zz,cmap=custom_cmap)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_decision_boundary(dt_clf,axis=[0.5,7.5,0,3])\n",
    "#可视化\n",
    "plt.scatter(X[y==0,0],X[y==0,1])\n",
    "plt.scatter(X[y==1,0],X[y==1,1])\n",
    "plt.scatter(X[y==2,0],X[y==2,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "模拟使用信息熵划分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import Counter\n",
    "\"\"\"\n",
    "a=[0,0,1,1,1]\n",
    "Counter(a)\n",
    "结果：Counter({1: 3, 0: 2})\n",
    "\"\"\"\n",
    "from math import log\n",
    "def split(X,y,d,value):\n",
    "    index_a=(X[:,d]<=value)#X对于d维度小于value值的元素索引,布尔型\n",
    "    index_b=(X[:,d]>value)\n",
    "    return X[index_a],X[index_b],y[index_a],y[index_b]\n",
    "def entropy(y):\n",
    "    counter=Counter(y)\n",
    "    res=0.0\n",
    "    for num in counter.values():\n",
    "        p=num/len(y)\n",
    "        res+=-p*log(p)\n",
    "    return res\n",
    "def try_split(X,y):\n",
    "    best_entropy=float(\"inf\")\n",
    "    best_d,best_v=-1,-1\n",
    "    for d in range(X.shape[1]):#遍历每一列\n",
    "        sorted_index=np.argsort(X[:,d])\n",
    "        for i in range(1,len(X)):#遍历d列的每一个元素\n",
    "            if X[sorted_index[i-1],d]!=X[sorted_index[i],d]:#确保相邻元素值不同\n",
    "                v=(X[sorted_index[i-1],d]+X[sorted_index[i],d])/2#阈值，分开两元素\n",
    "                X_l,X_r,y_l,y_r=split(X,y,d,v)#进行一次划分\n",
    "                e=entropy(y_l)+entropy(y_r)#计算当前划分方式下左子集和右子集的信息熵之和（越小越好！）\n",
    "                if e < best_entropy:\n",
    "                    best_entropy,best_d,best_v=e,d,v\n",
    "    return best_entropy,best_d,best_v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "best_entropy: 0.6931471805599453\n",
      "best_d: 0\n",
      "best_v: 2.45\n"
     ]
    }
   ],
   "source": [
    "#最佳划分\n",
    "best_entropy,best_d,best_v=try_split(X,y)\n",
    "print(\"best_entropy:\",best_entropy)\n",
    "print(\"best_d:\",best_d)\n",
    "print(\"best_v:\",best_v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#第一次划分\n",
    "X1_l,x1_r,y1_l,y1_r=split(X,y,best_d,best_v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "entropy(y1_l)#左侧划分的很稳定"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6931471805599453"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "entropy(y1_r)#右侧还需要划分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "best_entropy: 0.4132278899361904\n",
      "best_d: 1\n",
      "best_v: 1.75\n"
     ]
    }
   ],
   "source": [
    "#第二次划分\n",
    "best_entropy2,best_d2,best_v2=try_split(x1_r,y1_r)\n",
    "print(\"best_entropy:\",best_entropy2)\n",
    "print(\"best_d:\",best_d2)\n",
    "print(\"best_v:\",best_v2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "x2_l,x2_r,y2_l,y2_r=split(x1_r,y1_r,best_d2,best_v2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.30849545083110386"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "entropy(y2_l)#还可以继续分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.10473243910508653"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "entropy(y2_r)#还可以继续分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "之前scikit-learn设置2层深度树，所以对应此模拟划分两次\n",
    "\"\"\""
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
